const jwt = require('jsonwebtoken')
const { promisify } = require('util')
const R = require('@/models/Response')
const { userLoginToken } = require('@/config/config.default')
const { wpHget } = require('@/framework/redis/redisFn')
const { USER_TOKEN } = require('@/constants/user')
const { ERROR_USER_CODE } = require('@/constants/errorCode')

const tojwt = promisify(jwt.sign)
const verify = promisify(jwt.verify)

/**
 * @description token验证的中间件
 * @param {boolean} required 是否需要token才能调通此接口
 * @param {boolean} isReflesh 是否验证刷新token
 * @returns
 */
module.exports.verifyToken = function (required = true, isReflesh = false) {
  return async (ctx, next) => {
    var token = isReflesh ? ctx.headers.refleshtoken : ctx.headers.authorization
    token = token ? token.split('Bearer ')[1] : null
    if (token) {
      // 是否为刷新token验证验证
      try {
        const secret = isReflesh
          ? userLoginToken.refleshSecret
          : userLoginToken.secret
        const userInfo = await verify(token, secret)
        // 验证token的正确性，即token的确是该登录用户的
        let redisToken = await wpHget(USER_TOKEN, userInfo.id)
        redisToken = !isReflesh ? redisToken.token : redisToken.reflesh_token
        if (redisToken !== token) {
          ctx.body = R.error(ERROR_USER_CODE.USER_TOKEN_ERROR)
          return
        }
        ctx.user = {
          id: userInfo.id,
          username: userInfo.username
        }
      } catch {
        ctx.body = R.error(ERROR_USER_CODE.USER_TOKEN_ERROR)
        return
      }

      await next()
    } else if (required) {
      ctx.body = R.error(ERROR_USER_CODE.USER_TOKEN_ERROR)
    } else {
      await next()
    }
  }
}

/**
 * @description 生成token
 * @param {object} userInfo 用户信息
 * @param {string} secret token加密密钥
 * @param {number} expiresIn 过期时间
 * @returns {Promise<string>}  token字符串
 */
module.exports.createToken = async (userInfo, secret, expiresIn) => {
  var token = await tojwt(userInfo, secret, {
    expiresIn
  })
  return token
}

module.exports.verify = verify
